package mogelijkezetten;

import java.util.Scanner;
import ui.OthelloUserInterface;
import ui.UIHulpMethodes;
import ui.UserInterfaceFactory;
import ui.Event;

public class Orthello {

	OthelloUserInterface ui;
	private BeurtRij beurtRij;
	private BordRij bordRij;
	private final static int HOOGTE = OthelloUserInterface.AANTAL_KOLOMMEN;
	private final static int BREEDTE= OthelloUserInterface.AANTAL_RIJEN;
	private final static int MAX_AANTAL_BEURTEN = HOOGTE*BREEDTE*2;
	private int huidigeBeurt;

	Orthello(){
		UserInterfaceFactory.zetLageResolutie(true);
		beurtRij = new BeurtRij(MAX_AANTAL_BEURTEN);
		bordRij = new BordRij(MAX_AANTAL_BEURTEN);
		ui = UserInterfaceFactory.geefOthelloUI();
		UIHulpMethodes.vraagGebruikerOmInvoer();
	}

	public static void main(String[] argv) {
		new Orthello().start();
	}

	public void start(){
		Scanner in = new Scanner(System.in);
		leesBestand(in);
		verwerkInvoerTotBordRij();
		initialiseerBord();
		wachtOpInvoer();

	}

	/* LEES BESTAND IN BEGIN*/
	public void leesBestand(Scanner in){
		while(in.hasNext()){
			leesRegel(in.nextLine());
		}
		
	}

	public void leesRegel(String input){
		Scanner regel = new Scanner(input);
		boolean wit = leesWitOfZwart(regel.next());
		int denkTijd = regel.nextInt();
		boolean zet = leesZet(regel.next());				
		if(zet){
			beurtRij.voegBeurtToe(new Beurt(zet,wit,denkTijd,leesBeurt(regel)));
		} else{
			beurtRij.voegBeurtToe(new Beurt(zet,wit,denkTijd));
		}
	}

	public boolean leesWitOfZwart(String input){
		return input.contains("wit");
	}

	public boolean leesZet(String input){
		return input.contains("zet");
	}

	public Zet leesBeurt(Scanner regel){
		Coordinaat zetCoordinaat = leesCoordinaat(regel.next().charAt(0),regel.nextInt());
		CoordinaatRij coordinaatRij = new CoordinaatRij(HOOGTE * BREEDTE);
		while(regel.hasNext()){
			coordinaatRij.voegToe(leesCoordinaat(regel.next().charAt(0),regel.nextInt()));
		}
		return new Zet(zetCoordinaat,coordinaatRij);
	}

	public Coordinaat leesCoordinaat(char letter,int cijfer){
		letter -= 'a';
		return new Coordinaat(letter,cijfer -1);
	}

	/* LEES BESTAND IN EIND*/
	/* VERWERK INVOER TOT BORDRIJ IN BEGIN*/

	public void verwerkInvoerTotBordRij(){
		bordRij.voegToe(geefBeginBord());
		for(int i = 0;i < beurtRij.geefHuidigAantalBeurten();i++){
			bordRij.kopieerBord(i, i + 1);
			bordRij.voegToe(plaatsBeurtOpBord(bordRij.geefBord(i + 1),i));
		}
		beurtRij.voegBeurtToe(new Beurt(false, false, 0)); // tegen nullpointer einde beurten, nep pas toevoegen

	}

	public Bord geefBeginBord(){
		Bord beginBord = new Bord(BREEDTE,HOOGTE);
		beginBord.voegToe(3, 3, OthelloUserInterface.WIT);
		beginBord.voegToe(4, 4, OthelloUserInterface.WIT);
		beginBord.voegToe(3, 4, OthelloUserInterface.ZWART);
		beginBord.voegToe(4, 3, OthelloUserInterface.ZWART);
		return beginBord;
	}

	public Bord plaatsBeurtOpBord(Bord bord, int zetNummer){
		Beurt beurt = beurtRij.geefBeurt(zetNummer);
		if(beurt.geefZet()){
			bord = plaatsZetOpBord(bord,beurt.geefZetInhoud(),geefKleur(beurt));
		} 
		return bord;
	}

	public int geefKleur(Beurt beurt){
		if(beurt.geefWit())	return OthelloUserInterface.WIT;
		else 				return OthelloUserInterface.ZWART;

	}

	public Bord plaatsZetOpBord(Bord bord,Zet zet,int kleur){
		bord.voegToe(zet.geefZetCoordinaat(), kleur);
		bord = plaatsCoordinaatRijOpBord(bord,zet.geefVeranderdeStenen(),kleur);
		return bord;
	}

	public Bord plaatsCoordinaatRijOpBord(Bord bord,CoordinaatRij coordinaatRij,int kleur){
		for(int i = 0;i < coordinaatRij.geefAantalCoordinaten();i++){
			bord.voegToe(coordinaatRij.geefCoordinaten()[i], kleur);
		}
		return bord;
	}
	/* VERWERK INVOER TOT BORDRIJ IN EIND*/
	/* INITIALISEER BORD IN BEGIN*/
	public void initialiseerBord(){
		huidigeBeurt = (bordRij.geefAantalBorden() / 2);
		ui.printf("Aantal beurten geladen:%d\n",bordRij.geefAantalBorden());
		laatBordZien(bordRij.geefBord(huidigeBeurt));

	}



	public String geefSpelerNaam(Beurt beurt){
		if(beurt.geefWit()){
			return new String("wit");
		} else {
			return new String("zwart");
		}
	}

	public CoordinaatRij checkMogelijkeZetten(Bord bord,int kleur){
		CoordinaatRij resultaat = new CoordinaatRij(HOOGTE*BREEDTE);
		for(int i = 0;i < BREEDTE;i++){
			for(int j = 0;j < HOOGTE;j++){
				if(bord.geefWaarde(i, j) == OthelloUserInterface.LEEG){
					if(checkTussenliggendeStenen(new Coordinaat(i,j),kleur).geefAantalCoordinaten() > 0){
						resultaat.voegToe(new Coordinaat(i,j));
					}
				}
			}
		}
		return resultaat;

	}

	public CoordinaatRij checkTussenliggendeStenen(Coordinaat klik,int kleur){
		CoordinaatRij tussenliggendeStenen = new CoordinaatRij(HOOGTE*BREEDTE);
		if(bordRij.geefBord(huidigeBeurt).geefWaarde(klik) == OthelloUserInterface.LEEG){
			for(int i = 0;i < Richting.RICHTINGEN.length;i++){
				CoordinaatRij tmpCR = checkRichting(i,klik,kleur);
				tussenliggendeStenen.voegCoordinaatRijToe(tmpCR);
			}
		}
		return tussenliggendeStenen;
	}

	public CoordinaatRij checkRichting(int i,Coordinaat klikBackup,int kleur){
		CoordinaatRij tussenliggendEenRichting = new CoordinaatRij(HOOGTE*BREEDTE);
		Coordinaat klik = new Coordinaat(klikBackup.geefX(),klikBackup.geefY());

		Bord b = bordRij.geefBord(huidigeBeurt);
		klik.transleer(Richting.RICHTINGEN[i]);
		while(klik.geefX() < BREEDTE 		&& klik.geefY() < HOOGTE 
				&& 	klik.geefX() >= 0 		&& klik.geefY() >= 0){

			int kleurCheck = b.geefWaarde(klik);
			if(kleurCheck == geefInverseKleur(kleur)){
				tussenliggendEenRichting.voegToe(new Coordinaat(klik.geefX(), klik.geefY()));
			}
			else if(kleurCheck == kleur){
				if(tussenliggendEenRichting.geefAantalCoordinaten() > 0){
					return tussenliggendEenRichting;
				}
				else{
					return new CoordinaatRij(0);
				}
			}
			else if(kleurCheck == OthelloUserInterface.LEEG){
				return new CoordinaatRij(0);
			}
			klik.transleer(Richting.RICHTINGEN[i]);
		}
		return new CoordinaatRij(0);

	}

	public int geefInverseKleur(int kleur){
		if(kleur == OthelloUserInterface.ZWART)			return OthelloUserInterface.WIT;
		else if (kleur == OthelloUserInterface.LEEG)	return OthelloUserInterface.LEEG;
		else 											return OthelloUserInterface.ZWART;

	}

	public void plaatsDoorzichtig(CoordinaatRij coordinaatRij,int kleur){
		for(int i = 0;i<coordinaatRij.geefAantalCoordinaten();i++){
			ui.plaatsDoorzichtig(coordinaatRij.geefCoordinaten()[i].geefX(), coordinaatRij.geefCoordinaten()[i].geefY(), kleur);
		}
		ui.toon();
	}

	/* INITIALISEER BORD IN EIND*/
	/* WACHT OP INVOER IN BEGIN*/

	public void wachtOpInvoer(){
		while(true){
			Event event = ui.geefEvent();
			verwerkEvent(event);
		}
	}

	public void verwerkEvent(Event event){
		if(event.naam.equals("letter")) 			verwerkLetter(event); /* Als vervanging voor alt_cijfer*/
		else if (event.naam.equals("cijfer"))		verwerkCijfer(event);
		else if (event.naam.equals("mouseover"))			verwerkKlik(event);
		//else if (event.naam.equals("mouseover"))	{}
	}

	public void verwerkLetter(Event event){
		if(event.data.equals("x") && huidigeBeurt <= beurtRij.geefHuidigAantalBeurten()){
			verwerkSpringen(1);
		} else if (event.data.equals("z") && huidigeBeurt > 0){
			verwerkSpringen(-1);

		} else if (event.data.equals("a") || event.data.equals("b") || event.data.equals("c") || event.data.equals("d") || event.data.equals("e") || event.data.equals("f") || event.data.equals("g") || event.data.equals("h") || event.data.equals("i")){
			int nummer = ((event.data.charAt(0) - 'a' + 1)*-1);
			verwerkSpringen(nummer);
		} 

	}
	
//	public void verwerkMouseover(Event event){
//			Scanner klik = new Scanner(event.data);
//			Coordinaat coordinaat = leesCoordinaat(klik.next().charAt(0),klik.nextInt());
//			
//			if(checkMogelijkeZetten(bordRij.geefBord(huidigeBeurt),geefKleur(beurtRij.geefBeurt(huidigeBeurt))) ){
//				
//			}
//		}

	public void verwerkCijfer(Event event){
		verwerkSpringen(Integer.parseInt(event.data));
	}

	public void verwerkSpringen(int nummer){
		if(huidigeBeurt + nummer <= 0)										huidigeBeurt = 	0;
		else if(huidigeBeurt + nummer > bordRij.geefAantalBorden() - 1)		huidigeBeurt = 	bordRij.geefAantalBorden()-1;
		else																huidigeBeurt += nummer;
		
		
		laatBordZien(bordRij.geefBord(huidigeBeurt));
	}

	public void verwerkKlik(Event event){
		//ui.printf("KLIK!");
		laatBordZien(bordRij.geefBord(huidigeBeurt));
		//int tmpH = (huidigeBeurt >= beurtRij.geefHuidigAantalBeurten()-1 ?beurtRij.geefHuidigAantalBeurten()-1:huidigeBeurt);
		int kleur = geefKleur(beurtRij.geefBeurt(huidigeBeurt));

		Scanner klikScanner = new Scanner(event.data);
		Coordinaat coordinaat = leesCoordinaat(klikScanner.next().charAt(0),klikScanner.nextInt());
		CoordinaatRij ringen =  checkTussenliggendeStenen(coordinaat,kleur);

		if(ringen.geefAantalCoordinaten() > 0)		ui.plaatsDoorzichtig(coordinaat.geefX(),coordinaat.geefY(), kleur);
		//ui.printf("%d\t%d\t%d\n", coordinaat.geefX(),coordinaat.geefY(),kleur);
		plaatsOmcirkeling(ringen);
	}


	public void plaatsOmcirkeling(CoordinaatRij coordinaatRij){
		for(int i = 0;i<coordinaatRij.geefAantalCoordinaten();i++){
			ui.plaatsOmcirkeling(coordinaatRij.geefCoordinaten()[i].geefX(),coordinaatRij.geefCoordinaten()[i].geefY());
			//ui.printf("PLAATS:%d,%d", coordinaatRij.geefCoordinaten()[i].geefX(),coordinaatRij.geefCoordinaten()[i].geefY());
		}
		ui.toon();
	}

	public void laatBordZien(Bord bord){
		ui.maakLeeg();
		for(int i = 0;i < bord.geefLengte();i++){
			for(int j = 0;j < bord.geefHoogte();j++){
				ui.plaats(i, j, bord.geefWaarde(i, j));
			}
		}
		int tmpHuidigeBeurt = (huidigeBeurt-1>0?huidigeBeurt-1:0);
		ui.printf("Huidige beurt: %d, %s is aan zet.\n", huidigeBeurt,geefSpelerNaam(huidigeBeurt));
		int kleur = geefKleur(huidigeBeurt);
		plaatsDoorzichtig(checkMogelijkeZetten(bord,kleur),kleur);


		ui.toon();
	}
	
	public int geefKleur(int beurtNummer){
		if(beurtNummer % 2 == 0){
			return ui.ZWART;
		} else {
			return ui.WIT;
		}
	}
	
	public String geefSpelerNaam(int beurtNummer){
		if(beurtNummer % 2 == 0){
			return new String("zwart");
		} else {
			return new String("wit");
		}
	}

	/* WACHT OP INVOER IN EIND*/
	
}
